package io.gitee.binaryfox.firework;

import java.util.HashMap;
import java.util.Map;


class FireWorkSubString {
    /**
     * 按照ascii码升序,生成的字符串升序
     * 助于提高Mysql等b+数引擎的数据库中插入性能
     * 减少LSMTree的写入放大
     * 默认62位
     */
    private static String strArray = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
    /**
     * 生成char->int的映射
     */
    private static final Map<Character, Integer> characterToMap = new HashMap<>();

    static {
        for (int i = 0; i < strArray.length(); i++) {
            characterToMap.put(strArray.charAt(i), i);
        }
    }

    public static void setStrArray(String str) {
        strArray = str;
    }

    public static int len() {
        return strArray.length();
    }


    private char[] value;


    private FireWorkSubString(char[] value) {
        this.value = value;
    }

    public static FireWorkSubString of(String value) {
        return new FireWorkSubString(value.toCharArray());
    }

    /**
     * 从Long转RadixString
     * 超出位数部分直接抛弃
     *
     * @param value
     * @param len
     * @return
     */
    public static FireWorkSubString of(long value, int len) {
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < len; i++) {
            if (value != 0) {
                int charIndex = (int) (value % strArray.length());
                sb.append(strArray.charAt(charIndex));
                value = value / strArray.length();
            } else {
                sb.append(strArray.charAt(0));
            }
        }

        return new FireWorkSubString(sb.reverse().toString().toCharArray());
    }


    /**
     * 超过位数的部分进位直接抛弃
     * 用于序列号部分相加
     *
     * @param add 需要添加的值
     */
    public void addAtFixLen(long add) {
        if (add == 0) {
            return;
        }
        long sum = add;
        for (int i = 0; i < value.length; i++) {
            int index = value.length - i - 1;
            Integer integer = characterToMap.get(value[index]);
            sum = sum + integer;
            int charIndex = (int) (sum % strArray.length());
            if (charIndex < 0) {
                charIndex += strArray.length();
                sum -= strArray.length();
            }

            value[index] = strArray.charAt(charIndex);

            sum = sum / strArray.length();
            if (sum == 0) {
                break;
            }
        }
    }


    @Override
    public String toString() {
        return new String(value);
    }

    public long toLong() {
        long ret = 0;
        for (int i = 0; i < value.length; i++) {
            Integer integer = characterToMap.get(value[i]);
            ret = ret * strArray.length() + integer;
        }
        return ret;
    }


}
